package com.chinatechstar.prediction.service.impl;

import java.io.File;
import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import com.chinatechstar.admin.entity.SysUser;
import com.chinatechstar.admin.mapper.SysUserMapper;
import com.chinatechstar.component.commons.utils.CurrentUserUtils;
import com.chinatechstar.component.commons.utils.FileUtils;
import com.chinatechstar.component.commons.utils.PinyinUtils;
import com.chinatechstar.prediction.dto.PredictionOptimizationDTO;
import com.chinatechstar.prediction.dto.PredictionOptimizationDetailDTO;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.chinatechstar.prediction.entity.PredictionOptimization;
import com.chinatechstar.prediction.mapper.PredictionOptimizationMapper;
import com.chinatechstar.prediction.service.PredictionOptimizationService;
import com.chinatechstar.component.commons.result.PaginationBuilder;
import com.chinatechstar.component.commons.utils.SequenceGenerator;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import javax.servlet.http.HttpServletResponse;

/**
 * 业务逻辑实现层
 */
@Service
@Transactional
public class PredictionOptimizationServiceImpl implements PredictionOptimizationService {

    private final Logger logger = LoggerFactory.getLogger(getClass());
    private static final SequenceGenerator SEQUENCE_GENERATOR = new SequenceGenerator();
    private static final Long FILE_STORAGE_ID=871766848475983872L;
    @Autowired
    private PredictionOptimizationMapper predictionOptimizationMapper;
    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * 查询所有数据
     */
    @Override
    public List<PredictionOptimization> findPredictionOptimizationAll() {
        return predictionOptimizationMapper.findPredictionOptimizationAll();
    }

    /**
     * 查询分页
     */
    @Override
    public Map<String, Object> findPredictionOptimizationByCondition(Integer currentPage, Integer pageSize, String wellName, String wellSeg, String planName, String sorter) {
        Map<String, Object> paramMap = new HashMap<>();
        if (PinyinUtils.isEnglish(wellName)) {
            paramMap.put("pinyin", wellName);
        } else {
            paramMap.put("wellName", wellName);
        }
        paramMap.put("wellSeg", wellSeg);
        paramMap.put("planName", planName);
        if (StringUtils.isNotBlank(sorter)) {
            String sort = sorter.substring(0, sorter.lastIndexOf('_'));
            String sequence = "ascend".equals(sorter.substring(sorter.lastIndexOf('_') + 1)) ? "ASC" : "DESC";
            paramMap.put("sort", sort);
            paramMap.put("sequence", sequence);
        } else {
            paramMap.put("sort", "createTime");
            paramMap.put("sequence", "DESC");
        }
        Page<Object> page = PageHelper.startPage(currentPage, pageSize);
        List<LinkedHashMap<String, Object>> resultList = predictionOptimizationMapper.findPredictionOptimizationByCondition(paramMap);
        return PaginationBuilder.buildResult(resultList, page.getTotal(), currentPage, pageSize);
    }

    /**
     * 查询导出数据列表
     */
    @Override
    public List<LinkedHashMap<String, Object>> findPredictionOptimizationForExcel(Map<String, Object> paramMap) {
        return predictionOptimizationMapper.findPredictionOptimizationByCondition(paramMap);
    }

    /**
     * 根据压力和温度查询密度
     */
    @Override
    public List<PredictionOptimizationDTO> findWellCo2Density(Double formationPressure, Double formationTemperature) {

        return predictionOptimizationMapper.findWellCo2Density(formationPressure, formationTemperature);
    }

    /**
     * 导出
     */
    @Override
    public void exportPredictionOptimization(HttpServletResponse response) throws IOException {
        // 查询数据
        List<PredictionOptimization> dataList = predictionOptimizationMapper.findPredictionOptimizationAll();

        try {
            String templateFileName = FileUtils.getPath() + "templates" + File.separator + "注入参数优化数据导出模板.xlsx";
            templateFileName = URLDecoder.decode(templateFileName, "utf-8");
            String fileName = URLDecoder.decode("注入参数优化数据导出" + System.currentTimeMillis() + ".xlsx", "utf-8");

            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            response.setHeader("Content-disposition", "attachment; filename=" + new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));

            File file = new File(templateFileName);
            if (file.exists()) {
                EasyExcel.write(response.getOutputStream()).withTemplate(templateFileName).sheet(0).doFill(dataList);
            }
        } catch (Exception e) {
            response.reset();
            response.setContentType("application/json");
            response.setCharacterEncoding("utf-8");
            Map<String, String> resMap = new HashMap<>(2);
            resMap.put("status", "500");
            resMap.put("message", "下载文件失败：" + e.getMessage());
            response.getWriter().println(JSON.toJSONString(resMap));
        }
    }

    /**
    * 根据主键ID数据查询数据
    */
    @Override
    public PredictionOptimization findPredictionOptimizationById(Long id) {
        return predictionOptimizationMapper.findPredictionOptimizationById(id);
    }

    /**
    * 根据主键ID数组查询数据
    */
    @Override
    public List<PredictionOptimization> findPredictionOptimizationByIds(Long[] ids) {
        return predictionOptimizationMapper.findPredictionOptimizationByIds(ids);
    }

    /**
     * 新增
     */
    @Override
    public void insertPredictionOptimization(PredictionOptimization predictionOptimization) {
        SysUser currUser = sysUserMapper.getUserByUsername(CurrentUserUtils.getOAuth2AuthenticationInfo().get("name"));

        predictionOptimization.setId(SEQUENCE_GENERATOR.nextId());
        predictionOptimization.setCreateName(currUser.getNickname());
        predictionOptimization.setCreateUsername(currUser.getUsername());
        predictionOptimizationMapper.insertPredictionOptimization(predictionOptimization);

        // 创建初始文件
        HashMap<String, String> info = FileUtils.mkdirCommand(String.valueOf(predictionOptimization.getId()), FILE_STORAGE_ID, null, predictionOptimization.getId());
        logger.info("已新增： {}", predictionOptimization.getId());
        logger.info("创建文件夹：{}", info.get("dirName"));
    }

    /**
     * 批量新增
     */
    @Override
    public void insertPredictionOptimizations(List<PredictionOptimization> predictionOptimizations) {
        SysUser currUser = sysUserMapper.getUserByUsername(CurrentUserUtils.getOAuth2AuthenticationInfo().get("name"));

        for(PredictionOptimization predictionOptimization : predictionOptimizations) {
            predictionOptimization.setId(SEQUENCE_GENERATOR.nextId());
            predictionOptimization.setCreateName(currUser.getNickname());
            predictionOptimization.setCreateUsername(currUser.getUsername());
        }
        predictionOptimizationMapper.insertPredictionOptimizations(predictionOptimizations);
    }

    /**
     * 编辑
     */
    @Override
    public void updatePredictionOptimization(PredictionOptimization predictionOptimization) {
        predictionOptimizationMapper.updatePredictionOptimization(predictionOptimization);
        logger.info("已编辑： {}", predictionOptimization.getId());
    }

    /**
     * 批量编辑
     */
    @Override
    public void updatePredictionOptimizations(List<PredictionOptimization> predictionOptimizations) {
        predictionOptimizationMapper.updatePredictionOptimizations(predictionOptimizations);
    }

    /**
     * 删除
     */
    @Override
    public void deletePredictionOptimizationById(Long id) {
        predictionOptimizationMapper.deletePredictionOptimizationById(id);
    }

    /**
     * 批量删除
     */
    @Override
    public void deletePredictionOptimizationByIds(Long[] ids) {
        predictionOptimizationMapper.deletePredictionOptimizationByIds(ids);
    }


//    /**
//     * 软删除
//     */
//    @Override
//    public void softDeletePredictionOptimizationById(Long id) {
//        PredictionOptimization predictionOptimization = predictionOptimizationMapper.findPredictionOptimizationById(id);
//        if (predictionOptimization != null) {
//            predictionOptimization.setSoftDelete(0);
//            predictionOptimizationMapper.updatePredictionOptimization(predictionOptimization);
//        }
//
//    }
//
//    /**
//     * 批量软删除
//     */
//    @Override
//    public void softDeletePredictionOptimizationByIds(Long[] ids) {
//        List<PredictionOptimization> predictionOptimizations = predictionOptimizationMapper.findPredictionOptimizationByIds(ids);
//
//        if (predictionOptimizations.size() > 0) {
//            for (PredictionOptimization predictionOptimization :predictionOptimizations){
//                predictionOptimization.setSoftDelete(0);
//            }
//
//            predictionOptimizationMapper.updatePredictionOptimizations(predictionOptimizations);
//        }
//    }

    @Override
    public PredictionOptimizationDetailDTO getOptimizationDetail(Long id) {
        PredictionOptimization predictionOptimization;

        // 父级类
        PredictionOptimizationDetailDTO predictionOptimizationDetailDTO = new PredictionOptimizationDetailDTO();

        // 父级详情
        predictionOptimization = predictionOptimizationMapper.findPredictionOptimizationById(id);
        predictionOptimizationDetailDTO.setPredictionOptimizationDetail(predictionOptimization);
        return predictionOptimizationDetailDTO;
    }

    @Override
    public PredictionOptimization calculatePredictionOptimization(PredictionOptimization predictionOptimization){
        //计算
        predictionOptimization.setShortRadius(predictionOptimization.getInjectionThickness() / 2);
        if(predictionOptimization.getWellType()=="horizontal_well") {
            predictionOptimization.setWellBottomVolume(predictionOptimization.getPorosity() / 100 * predictionOptimization.getEmpiricalCoefficient() * 3.14 * predictionOptimization.getShortRadius() * predictionOptimization.getLongRadius() * predictionOptimization.getInjectionLength());
        }
        else{
            predictionOptimization.setWellBottomVolume(4*predictionOptimization.getPorosity()/100*predictionOptimization.getEmpiricalCoefficient()*3.14*predictionOptimization.getShortRadius()*Math.pow(predictionOptimization.getLongRadius(),2)/3);
        }
        predictionOptimization.setInjectionVolume(predictionOptimization.getWellBottomVolume() * predictionOptimization.getWellBottomDensity() );

        //取两位小数
        predictionOptimization.setWellBottomDensity((double) Math.round(predictionOptimization.getWellBottomDensity() * 10000) / 10000);
        predictionOptimization.setShortRadius((double) Math.round(predictionOptimization.getShortRadius() * 100) / 100);
        predictionOptimization.setWellBottomVolume((double) Math.round(predictionOptimization.getWellBottomVolume() * 100) / 100);
        return predictionOptimization;

    }
}
